package dbmgr

import (
	"UpdateManagerServer/models"
	"database/sql"
	"errors"
	"fmt"
	"math"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	"github.com/google/uuid"
)

var ErrRecordNotFound = errors.New("记录不存在")
var ErrDuplicateEntry = errors.New("数据已存在")

func NewBaseRepo() BaseRepo {
	return BaseRepo{
		mu: sync.Mutex{},
	}
}

type BaseRepo struct {
	mu sync.Mutex // 添加互斥锁
}

func (r *BaseRepo) getOrmer() orm.Ormer {
	return orm.NewOrm() // 每次获取新实例
}

// 检查唯一性冲突（排除当前记录）
func (r *BaseRepo) checkUnique(excludeId string, table string, field string, value interface{}) (bool, error) {
	qs := r.getOrmer().QueryTable(table).
		Filter(field, value)

		// 处理排除ID的类型转换
	if excludeId != "" {
		qs = qs.Exclude("id", excludeId)
	}

	exist := qs.Exist()
	return exist, nil
}

func (r *BaseRepo) CheckMissingIDs(dirNames []string) (map[string]bool, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	missing := make(map[string]bool)

	// 分批次处理（每批500个）
	batchSize := 500
	for i := 0; i < len(dirNames); i += batchSize {
		end := i + batchSize
		if end > len(dirNames) {
			end = len(dirNames)
		}
		batch := dirNames[i:end]

		// 构造ORM查询
		qs := o.QueryTable("version").
			Filter("id__in", batch).
			Limit(-1)

		var versions []*Version
		_, err := qs.All(&versions, "id")
		if err != nil {
			return nil, err
		}

		// 标记不存在项
		existMap := make(map[string]bool)
		for _, item := range versions {
			existMap[item.Id] = true
		}
		for _, name := range batch {
			if !existMap[name] {
				missing[name] = true
			}
		}
	}
	return missing, nil
}

// 获取版本详细信息
func (r *BaseRepo) Get_version(id string) (*Version, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	version := &Version{Id: id}
	err := r.getOrmer().Read(version)
	if err != nil {
		if err == orm.ErrNoRows {
			return nil, ErrRecordNotFound
		}
		return nil, fmt.Errorf("查询失败: %v", err)
	}
	return version, nil
}

// 查询最新版本记录
func (r *BaseRepo) GetLatestVersionByMachine(machineID int) (*Version, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	var version Version

	// 构建查询条件
	query := o.QueryTable("version").
		Filter("machine_id", machineID). // 按 machine_id 过滤:ml-citation{ref="2,3" data="citationList"}
		OrderBy("-created_at").          // 按时间降序排序:ml-citation{ref="2,3" data="citationList"}
		Limit(1)                         // 取第一条记录:ml-citation{ref="3" data="citationList"}

	// 执行查询
	err := query.One(&version)
	if err == orm.ErrNoRows {
		logs.Error("未找到 machine_id=%s 的记录", machineID)
		return nil, fmt.Errorf("未找到 machine_id=%d 的记录", machineID)
	} else if err != nil {
		logs.Error("数据库查询错误: %v", err)
		return nil, fmt.Errorf("数据库查询错误: %v", err)
	}

	return &version, nil
}

func (r *BaseRepo) List_versions(page, pageSize int, filter *Version) ([]*Version, int64, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	qs := o.QueryTable("version")

	// 动态构建过滤条件
	if filter != nil {
		// 主键精确匹配
		if filter.Id != "" {
			qs = qs.Filter("id", filter.Id)
		}
		// 名称模糊查询
		if filter.Name != "" {
			qs = qs.Filter("name__icontains", filter.Name)
		}
		// 版本号精确匹配
		if filter.Version != "" {
			qs = qs.Filter("version", filter.Version)
		}
		// 创建人ID匹配
		if filter.CreatorId != 0 {
			qs = qs.Filter("creator_id", filter.CreatorId)
		}
		// 机台关联查询
		if filter.Machine != nil && filter.Machine.Id != 0 {
			qs = qs.Filter("machine_id", filter.Machine.Id)
		}
		// 时间范围查询（示例：创建时间大于等于）
		if !filter.CreatedAt.IsZero() {
			qs = qs.Filter("created_at__gte", filter.CreatedAt)
		}
	}

	// 获取总数（自动包含过滤条件）
	total, err := qs.Count()
	if err != nil {
		return nil, 0, fmt.Errorf("查询总数失败: %v", err)
	}

	// 分页查询
	var versions []*Version
	_, err = qs.OrderBy("-created_at").
		Limit(pageSize, (page-1)*pageSize).
		All(&versions)

	if err != nil {
		return nil, 0, fmt.Errorf("查询列表失败: %v", err)
	}
	return versions, total, nil
}

// 创建版本
func (r *BaseRepo) Add_version(v *Version) (string, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	if v.Id == "" {
		v.Id = models.GenerateUUID()
	}

	// 自动填充创建时间
	if v.CreatedAt.IsZero() {
		v.CreatedAt = time.Now()
	}

	// 获取当前记录总数（事务内保证数据一致性）
	cnt, err := o.QueryTable("version").Filter("machine_id", v.Machine.Id).Count()
	if err != nil {
		logs.Error(err.Error())
		return v.Id, fmt.Errorf("查询记录数失败: %v", err)
	}

	// 生成版本号逻辑
	newCode := fmt.Sprintf("%d", cnt+1)
	v.Version = newCode

	_, err = o.Insert(v)
	if err != nil {
		logs.Error("insert err, %s, value: %s", err.Error(), v.ToJSON())
		return v.Id, err
	}

	return v.Id, err
}

// 删除版本及关联文件
func (r *BaseRepo) DeleteVersionWithFiles(id string) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer() // 使用统一ormer

	// 获取事务对象
	tx, err := o.Begin()
	if err != nil {
		return err
	}

	defer tx.Rollback() // 安全写法

	// 使用事务对象执行操作
	if _, err := tx.QueryTable("file").Filter("version_id", id).Delete(); err != nil {
		return err
	}

	if _, err := tx.Delete(&Version{Id: id}); err != nil {
		return err
	}

	return tx.Commit()
}

func (r *BaseRepo) UpdateVersionFilesMD5(versionId string) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer() // 使用统一ormer

	var files []File
	if _, err := o.QueryTable("file").Filter("version_id", versionId).All(&files); err != nil {
		return err
	}

	filespathmd5 := make([]models.FileMeta, 0)
	for _, file := range files {
		if file.MD5 != "" && !file.IsFolder {
			filespathmd5 = append(filespathmd5, models.FileMeta{Path: file.Path, MD5: file.MD5})
		}
	}

	combinedMD5 := models.CalculateCombinedMD5WithPath(filespathmd5)
	_, err := o.QueryTable("version").Filter("id", versionId).Update(orm.Params{
		"files_md5": combinedMD5,
	})
	return err
}

// 登录验证示例
func (r *BaseRepo) Login(account, password string) (*Employee, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	emp := &Employee{Account: account}
	if err := o.Read(emp, "Account"); err != nil {
		return emp, errors.New("账号不存在")
	}

	if !emp.CheckPassword(password) {
		return emp, errors.New("密码错误")
	}

	return emp, nil
}

// 获取员工详细信息
func (r *BaseRepo) Get_employee(id string) (*Employee, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	employee := &Employee{EmployeeId: id}
	err := r.getOrmer().Read(employee)
	if err != nil {
		if err == orm.ErrNoRows {
			return nil, ErrRecordNotFound
		}
		return nil, fmt.Errorf("查询失败: %v", err)
	}
	return employee, nil
}

// 获取员工详细信息
func (r *BaseRepo) Get_employeeByID(id int) (*Employee, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	employee := &Employee{ID: id}
	err := r.getOrmer().Read(employee)
	if err != nil {
		if err == orm.ErrNoRows {
			return nil, ErrRecordNotFound
		}
		return nil, fmt.Errorf("查询失败: %v", err)
	}
	return employee, nil
}

func (r *BaseRepo) CheckAccountExist(account string) bool {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	exist := o.QueryTable(new(Employee)).Filter("account", account).Exist()
	return exist
}

func (r *BaseRepo) GetEmployeeCount() (int64, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	count, err := o.QueryTable("employee").Count()

	return count, err
}

// 创建员工（带业务校验）
func (r *BaseRepo) Add_Employ(e *Employee) (*Employee, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	// 开启事务保证原子性
	tx, _ := o.Begin()
	defer tx.Rollback()

	if e.EmployeeId == "" {
		e.EmployeeId = models.GenerateUUID()
	}

	// 在事务内进行校验
	exit, err := r.checkUnique("", "employee", "employee_id", e.EmployeeId)
	if err != nil {
		return e, err
	}
	if exit {
		return e, ErrDuplicateEntry
	}

	// 执行插入
	if _, err := tx.Insert(e); err != nil {
		return e, err
	}

	return e, tx.Commit()
}

// 更新员工信息
func (r *BaseRepo) Update_Employ(id string, updateData map[string]interface{}) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	employee := &Employee{EmployeeId: id}
	err := o.Read(employee, "EmployeeId")
	if err != nil {
		logs.Error(err.Error())
		logs.Error(ErrRecordNotFound.Error() + ", emoloyeeid: " + id)
		return ErrRecordNotFound
	}

	// 动态更新逻辑
	if eid, ok := updateData["employee_id"]; ok {
		exit, err := r.checkUnique(employee.EmployeeId, "employee", "name", employee.Name)
		if err != nil {
			logs.Error(err.Error())
			return err
		}
		if exit {
			logs.Error("%w: 工号", ErrDuplicateEntry)
			return fmt.Errorf("%w: 工号", ErrDuplicateEntry)
		}
		employee.EmployeeId = eid.(string)
	}

	if phone, ok := updateData["phone"]; ok {
		exit, err := r.checkUnique(employee.EmployeeId, "employee", "name", employee.Name)
		if err != nil {
			return err
		}
		if exit {
			logs.Error("%w: 手机号", ErrDuplicateEntry)
			return fmt.Errorf("%w: 手机号", ErrDuplicateEntry)
		}
		employee.Phone = phone.(string)
	}

	if name, ok := updateData["name"]; ok {
		employee.Name = name.(string)
	}

	if isAdmin, ok := updateData["IsAdmin"]; ok {
		employee.IsAdmin = isAdmin.(int8)
	}

	if permission, ok := updateData["Permission"]; ok {
		employee.Permission = permission.(string)
	}

	_, err = o.Update(employee)
	return err
}

// 批量删除
func (r *BaseRepo) BatchDelete_Employ(ids []string) (int64, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	return r.getOrmer().QueryTable("employee").
		Filter("employee_id__in", ids).
		Delete()
}

func (r *BaseRepo) GetAllEmployees() ([]*Employee, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	var employees []*Employee

	// 使用QueryTable构建查询，推荐指定表别名
	_, err := o.QueryTable("employee").
		OrderBy("id"). // 按主键排序
		All(&employees)

	if err != nil {
		return nil, err
	}
	return employees, nil
}

// 自定义错误
var (
	ErrDuplicateMD5 = errors.New("同路径下的MD5值已存在")
)

// 获取单个文件
func (r *BaseRepo) GetFile(id string) (*File, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	file := &File{Id: id}
	err := r.getOrmer().Read(file)
	if err != nil {
		if err == orm.ErrNoRows {
			return nil, ErrRecordNotFound
		}
		return nil, fmt.Errorf("查询失败: %v", err)
	}

	// 加载关联版本
	_, _ = r.getOrmer().LoadRelated(file, "Version")
	return file, nil
}

// 查询联合唯一约束数据是否存在，存在则返回ID
func (r *BaseRepo) CheckUniqueAndGetID(fileName string, versionID string, path string) (string, bool, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	file := &File{}

	// 根据联合唯一键查询
	err := o.QueryTable("file").
		Filter("file_name", fileName).
		Filter("version_id", versionID). // 使用数据库列名 version_id ‌:ml-citation{ref="1,3" data="citationList"}
		Filter("path", path).
		One(file, "id") // 仅查询 Id 字段

	if err != nil {
		if err == orm.ErrNoRows {
			return "", false, nil // 数据不存在
		}
		return "", false, err // 查询异常
	}

	return file.Id, true, nil
}

// 根据版本号和路径查询文件
func (r *BaseRepo) GetFilesByVersionAndPath(version string, path string) ([]*File, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	path = strings.ReplaceAll(path, "\\", "/")

	var files []*File
	_, err := r.getOrmer().QueryTable("file").
		Filter("Path", path).           // 文件表路径条件
		Filter("Version__id", version). // 关联版本表的版本号条件
		All(&files)

	if err != nil {
		return nil, fmt.Errorf("查询失败: %v", err)
	}

	return files, nil
}

type FileSearchInfo struct {
	version_id string
	machine_id int
	parent_id  string
}

func (r *BaseRepo) GetFileTree(versionID string, machineID int, parentID string) ([]*File, int64, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	var results []*File
	var totalSize int64

	// 初始化队列（广度优先遍历）
	queue := []FileSearchInfo{
		{version_id: versionID, machine_id: machineID, parent_id: parentID},
	}

	// 已处理的父节点ID（防止循环）
	processedParents := make(map[string]bool)

	for len(queue) > 0 {
		current := queue[0]
		queue = queue[1:]

		// 查询当前层数据
		var files []*File
		_, err := o.QueryTable("file").
			Filter("version_id", current.version_id).
			Filter("machine_id", current.machine_id).
			Filter("parent_id", current.parent_id).
			All(&files)
		if err != nil {
			return nil, 0, fmt.Errorf("数据库查询失败: %v", err)
		}

		// 处理查询结果
		for _, file := range files {
			// 添加进最终结果
			results = append(results, file)

			totalSize += file.FileSize
			// 检查是否已处理过该父节点
			if !processedParents[file.Id] {
				// 将子节点加入队列
				queue = append(queue, FileSearchInfo{
					version_id: current.version_id,
					machine_id: current.machine_id,
					parent_id:  file.Id,
				})
				processedParents[file.Id] = true
			}
		}
	}

	return results, totalSize, nil
}

// 根据版本号和路径查询文件
func (r *BaseRepo) GetFilesByVersionAndParentID(machineID int, version string, parentID string) ([]*File, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	var files []*File
	_, err := r.getOrmer().QueryTable("file").
		Filter("parent_id", parentID).    // 文件表路径条件
		Filter("Version__id", version).   // 关联版本表的版本号条件
		Filter("Machine__id", machineID). // 关联版本表的版本号条件
		All(&files)

	if err != nil {
		return nil, fmt.Errorf("查询失败: %v", err)
	}

	return files, nil
}

// Filter("id__in", batch).
func (r *BaseRepo) GetFilesByVersionAndInParents(version string, parentsID []string) ([]*File, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	var files []*File
	_, err := r.getOrmer().QueryTable("file").
		Filter("parent_id__in", parentsID). // 文件表路径条件
		Filter("Version__id", version).     // 关联版本表的版本号条件
		All(&files)

	if err != nil {
		return nil, fmt.Errorf("查询失败: %v", err)
	}

	return files, nil
}

// 创建文件（带MD5校验）
func (r *BaseRepo) AddFile(f *File) (string, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	tx, _ := o.Begin()
	defer tx.Rollback()

	//存在相同文件
	exist := o.QueryTable("file").
		Filter("path", f.Path).
		Filter("file_name", f.FileName).
		Filter("version_id", f.Version.Id).
		Filter("machine_id", f.Machine.Id).
		Exist()
	if exist {
		return "", fmt.Errorf("存在相同文件,path:%s, filename: %s, version_id: %s", f.Path, f.FileName, f.Version.Id)
	}

	// 版本存在性校验
	if !o.QueryTable("version").
		Filter("id", f.Version.Id).
		Exist() {
		return "", fmt.Errorf("关联版本不存在")
	}

	// 生成UUID
	if f.Id == "" {
		f.Id = uuid.New().String()
	}

	// 执行插入
	if _, err := tx.Insert(f); err != nil {
		return "", fmt.Errorf("插入失败: %v", err)
	}

	return f.Id, tx.Commit()
}

// 检查文件夹是否存在
func (r *BaseRepo) IsFolderExist(versionID string, path string, name string) bool {
	r.mu.Lock()
	defer r.mu.Unlock()

	logs.Info("check exit, versionID: %s, path:%s, name:%s", versionID, path, name)

	o := r.getOrmer()
	qs := o.QueryTable("file").
		Filter("version_id", versionID).
		Filter("path", path).
		Filter("file_name", name).
		Filter("is_folder", true)
	return qs.Exist()
}

// 检查文件夹是否存在
func (r *BaseRepo) CheckFileExit(id string) bool {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	qs := o.QueryTable("file").
		Filter("id", id)

	return qs.Exist()
}

func (r *BaseRepo) CheckAndAddFileFolder(machineID int, versionID string, path string, name string, parentid string) (string, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	//logs.Info("yang start CheckAndAddFileFolder, file : %s", filepath.Join(path, name))

	o := r.getOrmer()

	// 检查 Version 是否存在
	versionExists := o.QueryTable("version").Filter("id", versionID).Exist()

	if !versionExists {
		return "", fmt.Errorf("版本不存在: %s", versionID)
	}

	// 启动事务
	tx, err := o.Begin()
	if err != nil {
		return "", fmt.Errorf("事务启动失败: %v", err)
	}
	defer func() {
		if tx != nil {
			_ = tx.Rollback()
		}
	}()

	var files []*File
	// 检查目录是否存在
	_, err = tx.QueryTable("file").
		Filter("version_id", versionID).
		Filter("path", path).
		Filter("file_name", name).
		Filter("is_folder", true).
		All(&files)

	if err != nil {
		logs.Error("查询失败: %v", err)
		return "", fmt.Errorf("查询失败: %v", err)
	}

	if len(files) == 1 {
		return files[0].Id, nil
	} else if len(files) > 1 {
		logs.Error("文件唯一性问题")
		return "", errors.New("文件唯一性问题")
	}

	// 创建目录记录
	f := File{
		Id:       uuid.New().String(), // 确保主键生成逻辑与数据库一致
		FileName: name,
		Version:  &Version{Id: versionID},
		Machine:  &Machine{Id: machineID},
		Path:     path,
		IsFolder: true,
		ParentId: parentid,
	}

	// 插入数据
	if _, err := tx.Insert(&f); err != nil {
		logs.Error("插入目录记录失败: %v", err)
		return "", fmt.Errorf("插入目录记录失败: %v", err)
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		logs.Error("提交事务失败: %v", err)
		return "", fmt.Errorf("提交事务失败: %v", err)
	}
	tx = nil // 阻止 defer 回滚
	return f.Id, nil
}

// 更新文件信息
func (r *BaseRepo) UpdateFileByID(id string, updateData map[string]interface{}) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	file := &File{Id: id}
	if err := o.Read(file); err != nil {
		return ErrRecordNotFound
	}

	// 动态更新逻辑
	needUpdate := false
	if fileName, ok := updateData["FileName"]; ok {
		file.FileName = fileName.(string)
		needUpdate = true
	}

	if md5, ok := updateData["MD5"]; ok {
		file.MD5 = md5.(string)
		needUpdate = true
	}

	if version, ok := updateData["Version"]; ok {
		// 版本存在性校验
		if !o.QueryTable("version").
			Filter("id", version.(*Version).Id).
			Exist() {
			return fmt.Errorf("指定版本不存在")
		}
		file.Version = version.(*Version)
		needUpdate = true
	}

	if needUpdate {
		_, err := o.Update(file, "FileName", "MD5", "Version")
		return err
	}
	return nil
}

// 更新文件信息（自动处理唯一约束冲突）
func (r *BaseRepo) UpdateFileByUnion(file *File, newFileName, newMD5, newPath string) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	// 开启事务（确保原子性）
	tx, _ := o.Begin()
	defer tx.Rollback() // 发生错误时自动回滚

	// 更新字段
	file.FileName = newFileName
	file.MD5 = newMD5
	file.Path = newPath

	// 执行更新
	_, err := o.Update(file, "file_name", "md5", "path")
	if err != nil {
		return err
	}

	// 提交事务
	err = tx.Commit()
	return err
}

// 批量删除文件
func (r *BaseRepo) BatchDeleteFiles(ids []string) (int64, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	// 级联校验（根据实际业务需求）
	if len(ids) == 0 {
		return 0, nil
	}

	return r.getOrmer().QueryTable("file").
		Filter("id__in", ids).
		Delete()
}

// 广度优先算法，文件删除
func (r *BaseRepo) DeleteFileCascade(machineID int, versionID string, id string) error {
	// 开启事务
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	tx, _ := o.Begin()
	defer tx.Rollback()

	// 使用队列实现广度优先删除
	currentLevelIDs := []string{id}
	for len(currentLevelIDs) > 0 {
		// 批量删除当前层数据
		_, err := tx.QueryTable("file").
			Filter("Version__id", versionID). // 关联 Version 表的主键
			Filter("Machine__id", machineID).
			Filter("id__in", currentLevelIDs).
			Delete()
		if err != nil {
			return fmt.Errorf("删除失败: %v", err)
		}

		// 获取下一层子节点ID
		var nextLevelFiles []*File
		_, err = tx.QueryTable("file").
			Filter("Version__id", versionID). // 关联 Version 表的主键
			Filter("Machine__id", machineID).
			Filter("parent_id__in", currentLevelIDs).
			All(&nextLevelFiles)
		if err != nil && err != orm.ErrNoRows {
			return fmt.Errorf("查询失败: %v", err)
		}

		// 准备下一轮循环数据
		currentLevelIDs = currentLevelIDs[:0]
		for _, f := range nextLevelFiles {
			currentLevelIDs = append(currentLevelIDs, f.Id)
		}
	}

	// 提交事务
	err := tx.Commit()
	if err != nil {
		return fmt.Errorf("事务提交失败: %v", err)
	}
	return nil
}

// 根据版本ID和路径批量删除文件
func (r *BaseRepo) DeleteFilesByVersionAndPath(machineID int, versionID string, path string, name string, isDir bool) (int64, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	// 路径格式标准化（根据实际存储规则）
	path = strings.ReplaceAll(path, "\\", "/")
	if !strings.HasSuffix(path, "/") {
		path += "/" // 确保路径以 / 结尾，避免部分匹配（如 /docs 匹配到 /docssss）
	}

	strFullPath := filepath.Join(path, name)
	strFullPath = strings.ReplaceAll(strFullPath, "\\", "/")
	if !strings.HasSuffix(strFullPath, "/") {
		strFullPath += "/" // 确保路径以 / 结尾，避免部分匹配（如 /docs 匹配到 /docssss）
	}

	if isDir {
		// 构建查询条件
		qs := r.getOrmer().QueryTable("file").
			Filter("Version__id", versionID). // 关联 Version 表的主键
			Filter("Machine__id", machineID).
			Filter("path", path).
			Filter("file_name", name)

		qsNext := r.getOrmer().QueryTable("file").
			Filter("Machine__id", machineID).
			Filter("Version__id", versionID). // 关联 Version 表的主键
			Filter("Path__istartswith", strFullPath)
		_, err := qsNext.Delete()
		if err != nil {
			return 0, err
		}

		return qs.Delete()
	} else {
		qs := r.getOrmer().QueryTable("file").
			Filter("Version__id", versionID). // 关联 Version 表的主键
			Filter("path", path).
			Filter("file_name", name)

		return qs.Delete()
	}
}

// 递归查询目录结构核心实现
func (r *BaseRepo) GetNestedFiles(parentID string) ([]*File, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer() // 获取 ORM 实例
	var result []*File

	// 使用 map 防止循环引用
	processed := make(map[string]bool)
	queue := []string{parentID}

	for len(queue) > 0 {
		currentParent := queue[0]
		queue = queue[1:]

		if processed[currentParent] {
			continue // 跳过已处理节点
		}
		processed[currentParent] = true

		// 批量查询当前层数据
		var currentFiles []*File
		_, err := o.QueryTable("file").
			Filter("parent_id", currentParent).
			All(&currentFiles)
		if err != nil {
			return nil, err
		}

		// 收集结果和下级节点
		for _, f := range currentFiles {
			result = append(result, f)
			if f.IsFolder { // 如果是文件夹才继续递归
				queue = append(queue, f.Id)
			}
		}
	}

	return result, nil
}

// 添加token
func (r *BaseRepo) AddAuthToken(f *AuthToken) (string, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	tx, _ := o.Begin()
	defer tx.Rollback()

	// 执行插入
	if _, err := tx.Insert(f); err != nil {
		return "", fmt.Errorf("插入失败: %v", err)
	}

	return f.Token, tx.Commit()
}

func (r *BaseRepo) CheckToken(f *AuthToken) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	err := o.Read(f)

	return err
}

func (r *BaseRepo) UpdateToken(f *AuthToken) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	_, err := o.Update(f, "LastActivity")

	return err
}

func (r *BaseRepo) ClearToken() error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	_, err := o.QueryTable(&AuthToken{}).
		Filter("expired_at__lt", time.Now()).
		Delete()

	return err
}

func (r *BaseRepo) GetByToken(token string) (*AuthToken, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	authToken := &AuthToken{}
	// 使用 QueryTable + Filter 进行精确查询
	err := o.QueryTable(authToken).
		Filter("Token", token).
		One(authToken)

	if err != nil {
		if err == orm.ErrNoRows {
			logs.Error("token不存在, token:%s", token)
			return nil, fmt.Errorf("token不存在")
		}
		logs.Error("查询数据库失败:%s", err.Error())
		return nil, fmt.Errorf("数据库查询错误: %v", err)
	}

	// 检查是否已撤销
	if authToken.IsRevoked {
		logs.Error("token已撤销")
		return nil, fmt.Errorf("token已撤销")
	}

	// 检查是否过期
	if time.Now().After(authToken.ExpiredAt) {
		logs.Error("token已过期")
		return nil, fmt.Errorf("token已过期")
	}

	return authToken, nil
}

// 生成递增的版本提交编号
func (r *BaseRepo) GenerateSubmissionNumber() (int, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	var maxNumber *int // 使用指针捕获 NULL

	// 查询当前最大编号（带行级锁）
	err := o.Raw(`
        SELECT MAX(submission_number)
        FROM file_submission`).QueryRow(&maxNumber)

	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return 1, nil // 无数据时返回初始编号 1:ml-citation{ref="1" data="citationList"}
		}
		logs.Error("查询最大值失败: %s", err.Error())
		return 0, fmt.Errorf("查询最大值失败: %v", err)
	}

	if maxNumber == nil {
		return 1, nil // 处理 NULL 值:ml-citation{ref="1" data="citationList"}
	}

	newNumber := *maxNumber + 1
	return newNumber, nil
}

func (r *BaseRepo) AddSubmission(sub *FileSubmission) (int, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	tx, _ := o.Begin()
	defer tx.Rollback()

	if _, err := tx.Insert(sub); err != nil {
		return 0, fmt.Errorf("创建提交记录失败: %v", err)
	}

	err := tx.Commit()
	if err != nil {
		logs.Error(err)
		return 0, err
	}

	return sub.ID, nil
}

type PageResult struct {
	Data       interface{} `json:"data"`       // 查询结果集
	Total      int64       `json:"total"`      // 总记录数
	Page       int         `json:"page"`       // 当前页码
	PageSize   int         `json:"pageSize"`   // 每页数量
	TotalPages int         `json:"totalPages"` // 总页数
}

type PageParams struct {
	Page     int    // 当前页码（默认1）
	PageSize int    // 每页数量（默认10）
	SortBy   string // 排序字段（默认submitted_at）
	Order    string // 排序顺序（desc/asc）
}

func (r *BaseRepo) QuerySubmissions(params PageParams) (PageResult, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	// 参数默认值处理:ml-citation{ref="1,6" data="citationList"}
	if params.Page <= 0 {
		params.Page = 1
	}
	if params.PageSize <= 0 {
		params.PageSize = 10
	}
	if params.SortBy == "" {
		params.SortBy = "submitted_at"
	}
	if params.Order == "" {
		params.Order = "desc"
	}

	o := r.getOrmer()
	qs := o.QueryTable("file_submission")

	// 计算总记录数:ml-citation{ref="3" data="citationList"}
	total, err := qs.Count()
	if err != nil {
		return PageResult{}, fmt.Errorf("查询总数失败: %v", err)
	}

	// 排序逻辑:ml-citation{ref="6" data="citationList"}
	orderBy := ""
	if params.Order == "asc" {
		orderBy = params.SortBy
	} else {
		orderBy = "-" + params.SortBy
	}

	// 分页查询:ml-citation{ref="3,4" data="citationList"}
	var subs []FileSubmission
	_, err = qs.OrderBy(orderBy).
		Limit(params.PageSize, (params.Page-1)*params.PageSize).
		All(&subs)
	if err != nil {
		return PageResult{}, fmt.Errorf("查询数据失败: %v", err)
	}

	return PageResult{
		Data:       subs,
		Total:      total,
		Page:       params.Page,
		PageSize:   params.PageSize,
		TotalPages: int(math.Ceil(float64(total) / float64(params.PageSize))),
	}, nil
}

func (r *BaseRepo) AddFileSubItem(item *FileSubItem) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	tx, _ := o.Begin()
	defer tx.Rollback()

	if exists := o.QueryTable("file_submission").
		Filter("id", item.FileSubmission).
		Exist(); !exists {
		logs.Error("关联提交记录不存在")
		return fmt.Errorf("关联提交记录不存在")
	}

	if _, err := tx.Insert(item); err != nil {
		logs.Error(err.Error())
		return fmt.Errorf("创建文件项失败: %v", err)
	}

	err := tx.Commit()
	if err != nil {
		logs.Error(err.Error())
		return err
	}
	return nil
}

func (r *BaseRepo) CreateMachine(m *Machine) (int64, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	// 获取当前记录总数（事务内保证数据一致性）
	cnt, err := o.QueryTable("machine").Count()
	if err != nil {
		logs.Error(err.Error())
		return 0, fmt.Errorf("查询记录数失败: %v", err)
	}

	// 生成版本号逻辑
	newCode := fmt.Sprintf("v%d", cnt+1)
	m.Code = newCode

	// 自动填充创建时间（由orm标签auto_now_add处理）
	id, err := o.Insert(m)
	if err != nil {
		if strings.Contains(err.Error(), "Duplicate entry") {
			return 0, fmt.Errorf("机台编号已存在")
		}
		return 0, fmt.Errorf("创建失败: %v", err)
	}
	return id, nil
}

func (r *BaseRepo) GetMachineById(id int) (*Machine, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	machine := &Machine{Id: id}
	err := o.Read(machine)
	if err != nil {
		if err == orm.ErrNoRows {
			return nil, fmt.Errorf("机台不存在")
		}
		return nil, fmt.Errorf("查询失败: %v", err)
	}
	return machine, nil
}

func (r *BaseRepo) GetMachineByCode(code string) (*Machine, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()
	machine := &Machine{Code: code}
	err := o.Read(machine, "Code")
	if err != nil {
		logs.Error(err.Error())
		if err == orm.ErrNoRows {
			return nil, fmt.Errorf("机台不存在")
		}
		return nil, fmt.Errorf("查询失败: %v", err)
	}
	return machine, nil
}

func (r *BaseRepo) GetMachines(condition *Machine) ([]*Machine, error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	qs := o.QueryTable("machine")

	// 动态构建查询条件
	if condition.Id != 0 {
		qs = qs.Filter("Id", condition.Id)
	}
	if condition.Name != "" {
		qs = qs.Filter("Name__icontains", condition.Name)
	}
	if condition.Code != "" {
		qs = qs.Filter("Code", condition.Code)
	}
	if condition.CreatorId != 0 {
		qs = qs.Filter("CreatorId", condition.CreatorId)
	}

	var machines []*Machine
	_, err := qs.All(&machines)
	return machines, err
}

func (r *BaseRepo) DeleteMachine(id int) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	o := r.getOrmer()

	if _, err := o.Delete(&Machine{Id: id}); err != nil {
		if strings.Contains(err.Error(), "a foreign key constraint fails") {
			return fmt.Errorf("存在关联数据，禁止删除")
		}
		return fmt.Errorf("删除失败: %v", err)
	}
	return nil
}
